﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace Kyoh.Lib.WinForms
{
    /// <summary>デザイナなどにおけるファイル/ディレクトリパスのエディタを提供します。</summary>
    public partial class PathEditor : UserControl
    {
        /// <summary>ファイル/ディレクトリパスの検証結果を示す列挙子。</summary>
        public enum PathValidation
        {
            /// <summary>空文字列。</summary>
            Empty,
            /// <summary>有効なパス。</summary>
            Valid,
            /// <summary>無効なパス。</summary>
            Invalid,
        }

        /// <summary><see cref="PathEditor"/> クラスの新しいインスタンスを初期化します。</summary>
        public PathEditor()
        {
            InitializeComponent();
            this.CheckPath();
        }

        /// <summary>コンテナのコントロールからの要求に従い、入力のチェックを行います。</summary>
        /// <returns>入力が妥当である場合は <c>true</c>。それ以外の場合は <c>false</c>。</returns>
        public override bool ValidateChildren()
        {
            this.CheckPath();
            return this.Valid == PathValidation.Valid;
        }

        /// <summary>パスのチェックを行う場合、このメソッドをオーバーライドします。</summary>
        /// <param name="path">検証対象のパス文字列。</param>
        /// <returns>パスの妥当性を表す <see cref="PathEditor.PathValidation"/> 値。</returns>
        protected virtual PathValidation CheckPath(string path)
        {
            return PathValidation.Empty;
        }

        /// <summary>ユーザーからのパスの入力を受け付ける場合、このメソッドをオーバーライドします。</summary>
        /// <returns>ユーザの入力したパス。</returns>
        protected virtual string SelectPath()
        {
            return null;
        }

        private bool CheckPath()
        {
            switch (this.CheckPath(this.pathTextBox.Text))
            {
                case PathValidation.Empty:
                    this.panel1.BackgroundImage = Properties.Resources.exclamation_16;
                    this.pathTextBox.BackColor = Color.LightPink;
                    return false;
                case PathValidation.Valid:
                    this.panel1.BackgroundImage = Properties.Resources.accept_16;
                    this.pathTextBox.BackColor = Color.Aquamarine;
                    return true;
                default:
                    this.panel1.BackgroundImage = Properties.Resources.error_16;
                    this.pathTextBox.BackColor = Color.Khaki;
                    return false;
            }
        }

        /// <summary>ファイル/ディレクトリパスを取得・設定します。</summary>
        public string Path
        {
            get { return this.pathTextBox.Text; }
            set
            {
                this.pathTextBox.Text = value;
                this.CheckPath();
            }
        }

        /// <summary>ファイル/ディレクトリパスの検証結果を取得します。</summary>
        public PathValidation Valid
        {
            get { return this.CheckPath(this.pathTextBox.Text); }
        }

        private void selectorButton_Click(object sender, EventArgs e)
        {
            this.pathTextBox.Text = this.SelectPath() ?? this.pathTextBox.Text;
            this.CheckPath();
        }

        private void pathTextBox_Validating(object sender, CancelEventArgs e)
        {
            this.CheckPath();
        }

        private void pathTextBox_Validated(object sender, EventArgs e)
        {
            try
            {
                string path = this.pathTextBox.Text;
                FileSystemInfo info = null;
                if (File.Exists(path))
                    info = new FileInfo(path);
                else if (Directory.Exists(path))
                    info = new DirectoryInfo(path);
                if (info != null)
                    this.pathTextBox.Text = info.FullName;
            }
            catch { }
        }
    }
}
